/**
 * 错误处理工具类
 * 
 * 提供统一的错误处理机制，包括错误类型定义、错误处理方法、
 * 错误日志记录和用户友好的错误提示等功能。
 * 
 * @fileoverview 错误处理工具类，提供统一的错误处理机制
 * @author HarmonyOS开发团队
 * @version 1.0.0
 */

import hilog from '@ohos.hilog';

/**
 * 错误级别枚举
 * 
 * 定义了错误的严重程度级别，用于错误分类和处理。
 */
export enum ErrorLevel {
  INFO = 'info',       // 信息级别
  WARNING = 'warning', // 警告级别
  ERROR = 'error',     // 错误级别
  CRITICAL = 'critical' // 严重错误级别
}

/**
 * 错误类型枚举
 * 
 * 定义了应用中可能出现的错误类型，用于错误分类和特定处理。
 */
export enum ErrorType {
  NETWORK = 'network',         // 网络错误
  API = 'api',                 // API错误
  VALIDATION = 'validation',   // 验证错误
  PERMISSION = 'permission',   // 权限错误
  SYSTEM = 'system',           // 系统错误
  UNKNOWN = 'unknown'          // 未知错误
}

/**
 * 应用错误接口
 * 
 * 定义了应用中的标准错误结构，包含错误码、消息、类型等详细信息。
 */
export interface AppError {
  code: string;              // 错误码
  message: string;           // 错误消息
  type: ErrorType;           // 错误类型
  level: ErrorLevel;         // 错误级别
  details?: any;             // 错误详情（可选）
  timestamp: string;         // 错误时间戳
  stack?: string;            // 错误堆栈（可选）
}

/**
 * 错误处理结果接口
 * 
 * 定义了错误处理的结果结构，包含处理状态和相关信息。
 */
export interface ErrorHandlingResult {
  handled: boolean;          // 是否已处理
  message?: string;          // 处理结果消息（可选）
  action?: string;           // 建议操作（可选）
  shouldRetry?: boolean;     // 是否建议重试（可选）
  retryDelay?: number;       // 重试延迟（毫秒，可选）
}

/**
 * 错误处理器接口
 * 
 * 定义了错误处理器的标准接口，用于自定义错误处理逻辑。
 */
export interface ErrorHandler {
  canHandle(error: AppError): boolean;     // 判断是否可以处理该错误
  handle(error: AppError): ErrorHandlingResult; // 处理错误
}

/**
 * 错误处理工具类
 * 
 * 提供统一的错误处理机制，包括错误创建、日志记录、错误处理等功能。
 */
export class ErrorUtils {
  // 日志标签
  private static readonly TAG = 'ErrorUtils';
  
  // 错误处理器列表
  private static errorHandlers: ErrorHandler[] = [];
  
  // 默认错误码前缀
  private static readonly DEFAULT_ERROR_CODE_PREFIX = 'APP_ERROR';
  
  // 错误计数器
  private static errorCounter = 0;
  
  /**
   * 创建应用错误
   * 
   * 根据提供的参数创建一个标准的应用错误对象。
   * 
   * @param code 错误码
   * @param message 错误消息
   * @param type 错误类型
   * @param level 错误级别
   * @param details 错误详情（可选）
   * @param stack 错误堆栈（可选）
   * @returns 应用错误对象
   */
  public static createError(
    code: string,
    message: string,
    type: ErrorType = ErrorType.UNKNOWN,
    level: ErrorLevel = ErrorLevel.ERROR,
    details?: any,
    stack?: string
  ): AppError {
    return {
      code,
      message,
      type,
      level,
      details,
      timestamp: new Date().toISOString(),
      stack
    };
  }
  
  /**
   * 从异常创建应用错误
   * 
   * 将JavaScript异常转换为应用错误对象。
   * 
   * @param exception JavaScript异常
   * @param type 错误类型（可选）
   * @param level 错误级别（可选）
   * @param details 错误详情（可选）
   * @returns 应用错误对象
   */
  public static fromException(
    exception: Error,
    type: ErrorType = ErrorType.UNKNOWN,
    level: ErrorLevel = ErrorLevel.ERROR,
    details?: any
  ): AppError {
    const code = `${this.DEFAULT_ERROR_CODE_PREFIX}_${++this.errorCounter}`;
    return this.createError(
      code,
      exception.message || '未知错误',
      type,
      level,
      details,
      exception.stack
    );
  }
  
  /**
   * 记录错误日志
   * 
   * 将错误信息记录到系统日志中。
   * 
   * @param error 应用错误对象
   */
  public static logError(error: AppError): void {
    const logMessage = `错误[${error.code}]: ${error.message} | 类型: ${error.type} | 级别: ${error.level}`;
    
    switch (error.level) {
      case ErrorLevel.INFO:
        hilog.info(0x0000, this.TAG, logMessage);
        break;
      case ErrorLevel.WARNING:
        hilog.warn(0x0000, this.TAG, logMessage);
        break;
      case ErrorLevel.ERROR:
        hilog.error(0x0000, this.TAG, logMessage);
        break;
      case ErrorLevel.CRITICAL:
        hilog.error(0x0000, this.TAG, `严重错误 - ${logMessage}`);
        break;
      default:
        hilog.error(0x0000, this.TAG, logMessage);
    }
    
    // 记录错误详情
    if (error.details) {
      hilog.debug(0x0000, this.TAG, `错误详情: ${JSON.stringify(error.details)}`);
    }
    
    // 记录错误堆栈
    if (error.stack) {
      hilog.debug(0x0000, this.TAG, `错误堆栈: ${error.stack}`);
    }
  }
  
  /**
   * 处理错误
   * 
   * 使用注册的错误处理器处理错误，并返回处理结果。
   * 
   * @param error 应用错误对象
   * @returns 错误处理结果
   */
  public static handleError(error: AppError): ErrorHandlingResult {
    // 记录错误日志
    this.logError(error);
    
    // 查找可以处理该错误的处理器
    for (const handler of this.errorHandlers) {
      if (handler.canHandle(error)) {
        try {
          return handler.handle(error);
        } catch (e) {
          const handlerError = this.fromException(
            e as Error,
            ErrorType.SYSTEM,
            ErrorLevel.ERROR,
            { originalError: error }
          );
          this.logError(handlerError);
        }
      }
    }
    
    // 默认处理结果
    return {
      handled: false,
      message: '发生未知错误，请稍后重试',
      action: '请联系技术支持',
      shouldRetry: true,
      retryDelay: 3000
    };
  }
  
  /**
   * 注册错误处理器
   * 
   * 向错误处理工具类注册一个自定义错误处理器。
   * 
   * @param handler 错误处理器
   */
  public static registerErrorHandler(handler: ErrorHandler): void {
    this.errorHandlers.push(handler);
  }
  
  /**
   * 移除错误处理器
   * 
   * 从错误处理工具类移除一个已注册的错误处理器。
   * 
   * @param handler 要移除的错误处理器
   */
  public static removeErrorHandler(handler: ErrorHandler): void {
    const index = this.errorHandlers.indexOf(handler);
    if (index !== -1) {
      this.errorHandlers.splice(index, 1);
    }
  }
  
  /**
   * 创建网络错误
   * 
   * 创建一个网络类型的应用错误。
   * 
   * @param message 错误消息
   * @param details 错误详情（可选）
   * @returns 网络错误对象
   */
  public static createNetworkError(message: string, details?: any): AppError {
    return this.createError(
      'NETWORK_ERROR',
      message,
      ErrorType.NETWORK,
      ErrorLevel.ERROR,
      details
    );
  }
  
  /**
   * 创建API错误
   * 
   * 创建一个API类型的应用错误。
   * 
   * @param code 错误码
   * @param message 错误消息
   * @param details 错误详情（可选）
   * @returns API错误对象
   */
  public static createApiError(code: string, message: string, details?: any): AppError {
    return this.createError(
      code,
      message,
      ErrorType.API,
      ErrorLevel.ERROR,
      details
    );
  }
  
  /**
   * 创建验证错误
   * 
   * 创建一个验证类型的应用错误。
   * 
   * @param message 错误消息
   * @param details 错误详情（可选）
   * @returns 验证错误对象
   */
  public static createValidationError(message: string, details?: any): AppError {
    return this.createError(
      'VALIDATION_ERROR',
      message,
      ErrorType.VALIDATION,
      ErrorLevel.WARNING,
      details
    );
  }
  
  /**
   * 创建权限错误
   * 
   * 创建一个权限类型的应用错误。
   * 
   * @param message 错误消息
   * @param details 错误详情（可选）
   * @returns 权限错误对象
   */
  public static createPermissionError(message: string, details?: any): AppError {
    return this.createError(
      'PERMISSION_ERROR',
      message,
      ErrorType.PERMISSION,
      ErrorLevel.ERROR,
      details
    );
  }
  
  /**
   * 创建系统错误
   * 
   * 创建一个系统类型的应用错误。
   * 
   * @param message 错误消息
   * @param details 错误详情（可选）
   * @returns 系统错误对象
   */
  public static createSystemError(message: string, details?: any): AppError {
    return this.createError(
      'SYSTEM_ERROR',
      message,
      ErrorType.SYSTEM,
      ErrorLevel.CRITICAL,
      details
    );
  }
}

/**
 * 网络错误处理器
 * 
 * 专门处理网络类型错误的错误处理器。
 */
export class NetworkErrorHandler implements ErrorHandler {
  canHandle(error: AppError): boolean {
    return error.type === ErrorType.NETWORK;
  }
  
  handle(error: AppError): ErrorHandlingResult {
    return {
      handled: true,
      message: '网络连接失败，请检查网络设置',
      action: '检查网络连接后重试',
      shouldRetry: true,
      retryDelay: 5000
    };
  }
}

/**
 * API错误处理器
 * 
 * 专门处理API类型错误的错误处理器。
 */
export class ApiErrorHandler implements ErrorHandler {
  canHandle(error: AppError): boolean {
    return error.type === ErrorType.API;
  }
  
  handle(error: AppError): ErrorHandlingResult {
    // 根据错误码进行不同处理
    if (error.code === '401' || error.code === '403') {
      return {
        handled: true,
        message: '您没有权限执行此操作',
        action: '请重新登录',
        shouldRetry: false
      };
    } else if (error.code === '404') {
      return {
        handled: true,
        message: '请求的资源不存在',
        action: '请检查请求地址',
        shouldRetry: false
      };
    } else if (error.code === '500') {
      return {
        handled: true,
        message: '服务器内部错误',
        action: '请稍后重试',
        shouldRetry: true,
        retryDelay: 3000
      };
    } else {
      return {
        handled: true,
        message: 'API请求失败',
        action: '请稍后重试',
        shouldRetry: true,
        retryDelay: 3000
      };
    }
  }
}

/**
 * 验证错误处理器
 * 
 * 专门处理验证类型错误的错误处理器。
 */
export class ValidationErrorHandler implements ErrorHandler {
  canHandle(error: AppError): boolean {
    return error.type === ErrorType.VALIDATION;
  }
  
  handle(error: AppError): ErrorHandlingResult {
    return {
      handled: true,
      message: '输入数据验证失败',
      action: '请检查输入数据',
      shouldRetry: false
    };
  }
}

/**
 * 权限错误处理器
 * 
 * 专门处理权限类型错误的错误处理器。
 */
export class PermissionErrorHandler implements ErrorHandler {
  canHandle(error: AppError): boolean {
    return error.type === ErrorType.PERMISSION;
  }
  
  handle(error: AppError): ErrorHandlingResult {
    return {
      handled: true,
      message: '权限不足，无法执行此操作',
      action: '请联系管理员获取权限',
      shouldRetry: false
    };
  }
}

/**
 * 系统错误处理器
 * 
 * 专门处理系统类型错误的错误处理器。
 */
export class SystemErrorHandler implements ErrorHandler {
  canHandle(error: AppError): boolean {
    return error.type === ErrorType.SYSTEM;
  }
  
  handle(error: AppError): ErrorHandlingResult {
    return {
      handled: true,
      message: '系统错误，请稍后重试',
      action: '如果问题持续存在，请联系技术支持',
      shouldRetry: true,
      retryDelay: 10000
    };
  }
}

// 注册默认错误处理器
ErrorUtils.registerErrorHandler(new NetworkErrorHandler());
ErrorUtils.registerErrorHandler(new ApiErrorHandler());
ErrorUtils.registerErrorHandler(new ValidationErrorHandler());
ErrorUtils.registerErrorHandler(new PermissionErrorHandler());
ErrorUtils.registerErrorHandler(new SystemErrorHandler());